package cn.ecnu.user.util;

import cn.ecnu.common.Constant;
import cn.ecnu.common.RedisConstant;
import cn.ecnu.exception.RRXException;
import cn.ecnu.vo.user.UserPermission;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.UUID;


@ConfigurationProperties(prefix = "paper.token")
@Component
@Slf4j
public class TokenSolver {

    private long expire = 100; // 100分钟的过期时间


    @Autowired
    RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;


    /**
     * 生成token
     */
    public String sign(UserPermission userPermission) throws JsonProcessingException {
        String token = UUID.randomUUID().toString().substring(0, 10); // 生成token
        String uid2Token = RedisConstant.USER_TOKEN + userPermission.getUserId();
        String token2Uid = RedisConstant.TOKEN_USER + token;
        // 首先看是否已经登录
        String lastToken = stringRedisTemplate.opsForValue().get(uid2Token);
        if (!StringUtils.isEmpty(lastToken)) {
            stringRedisTemplate.delete(RedisConstant.TOKEN_USER + lastToken); // 作废这个token
        }
        redisTemplate.opsForValue().set(RedisConstant.TOKEN_USER + token, userPermission, Duration.ofMinutes(expire)); // 在redis中进行设置这个token --> id%auth
        stringRedisTemplate.opsForValue().set(RedisConstant.USER_TOKEN + userPermission.getUserId(), token, Duration.ofMinutes(expire)); // id --> token
        log.info(token);
        return token;
    }

    /**
     * 根据token获取UserPermission
     * @param token
     * @return
     */
    public UserPermission getUser(String token) {
        UserPermission user =  (UserPermission) redisTemplate.opsForValue().get(RedisConstant.TOKEN_USER + token);
        if (user == null) throw new RRXException(Constant.TOKEN_MISSING.getMsg(), Constant.TOKEN_MISSING.getCode());
        return user;
    }

    /**
     * 根据用户id获取token
     * @param userId
     * @return
     */
    public String getTokenByUserId(Integer userId) {
        String token = stringRedisTemplate.opsForValue().get(RedisConstant.USER_TOKEN + userId);
        if (!StringUtils.hasLength(token)) throw new RRXException(Constant.TOKEN_MISSING.getMsg(), Constant.TOKEN_MISSING.getCode());
        return token;
    }

}
